package org.jeecg.modules.demo.hd.controller;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.HttpServletRequestUtil;
import org.jeecg.common.util.IpUtils;
import org.jeecg.common.vo.RequestVo;
import org.jeecg.modules.demo.hd.entity.AppMyProjectClickdetail;
import org.jeecg.modules.demo.hd.entity.AppSpace;
import org.jeecg.modules.demo.hd.service.IAppMyProjectClickdetailService;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;

import org.jeecg.modules.demo.hd.service.IAppSpaceService;
import org.jeecg.modules.demo.hd.vo.ClickStatusVo;
import org.jeecg.modules.demo.hd.vo.myProject.AppMyProjectClickdetailModelVo;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.modules.demo.hd.vo.myProject.ClickDetailDayStatisticsVo;
import org.jeecg.modules.system.entity.AppDeviceFreeze;
import org.jeecg.modules.system.entity.AppUserDeviceLog;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.IAppDeviceFreezeService;
import org.jeecg.modules.system.service.IAppUserDeviceLogService;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;

/**
 * @Description: 用户点击广告任务返回数据
 * @Author: jeecg-boot
 * @Date: 2025-04-16
 * @Version: V1.0
 */
@Api(tags = "用户点击广告任务返回数据")
@RestController
@RequestMapping("/hd/appMyProjectClickdetail")
@Slf4j
public class AppMyProjectClickdetailController extends JeecgController<AppMyProjectClickdetail, IAppMyProjectClickdetailService> {
    @Autowired
    private IAppMyProjectClickdetailService appMyProjectClickdetailService;

    @Autowired
    private IAppSpaceService spaceService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private IAppUserDeviceLogService deviceLogService;

    @Resource
    private IAppDeviceFreezeService deviceFreezeService;


    /**
     * 分页列表查询
     *
     * @param appMyProjectClickdetail
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    //@AutoLog(value = "app_my_project_clickdetail-分页列表查询")
    @ApiOperation(value = "查询所有点击奖励", notes = "查询所有点击奖励")
    @GetMapping(value = "/list")
    public Result<IPage<AppMyProjectClickdetail>> queryPageList(AppMyProjectClickdetail appMyProjectClickdetail,
                                                                @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                                @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                                HttpServletRequest req) {
        QueryWrapper<AppMyProjectClickdetail> queryWrapper = QueryGenerator.initQueryWrapper(appMyProjectClickdetail, req.getParameterMap());
        Page<AppMyProjectClickdetail> page = new Page<AppMyProjectClickdetail>(pageNo, pageSize);
        IPage<AppMyProjectClickdetail> pageList = appMyProjectClickdetailService.page(page, queryWrapper);
        return Result.OK(pageList);
    }

    /**
     * 添加广告任务返回数据
     *
     * @param vo
     * @return
     */
    @AutoLog(value = "添加广告任务返回数据")
    @ApiOperation(value = "添加广告任务返回数据", notes = "添加广告任务返回数据")
    @PostMapping(value = "/add")
    public Result<String> add(@RequestBody AppMyProjectClickdetailModelVo vo, HttpServletRequest req) {
        AppMyProjectClickdetail model = new AppMyProjectClickdetail();
        BeanUtils.copyProperties(vo, model);
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        // 保存设备请求日志
        RequestVo requestVo = HttpServletRequestUtil.getDeviceInfoVo(req);
        AppUserDeviceLog deviceInfoVo = new AppUserDeviceLog();
        BeanUtils.copyProperties(requestVo, deviceInfoVo);
        List<AppDeviceFreeze> deviceFreezeList = deviceFreezeService.getList();

        if (deviceFreezeList != null && deviceFreezeList.size() > 0) {
            long count = deviceFreezeList.stream()
                    .filter(x -> x.getDeviceId().equals(deviceInfoVo.getDeviceId()) && x.getStatus().equals("0")).count();
            if (count > 0) {
                return Result.OK("0");
            }
        }

        deviceInfoVo.setUserId(sysUser.getId());
        deviceInfoVo.setRequestUrl("添加广告任务返回数据");
        deviceLogService.save(deviceInfoVo);

        model.setUserId(sysUser.getId());
//      req.getParameter("biz");
        // 保存点击返回数据
        String ipAddr = IpUtils.getIpAddr(req);
        model.setIp(ipAddr);
        String s = appMyProjectClickdetailService.addDetail(model);
        return Result.OK(s);
    }

    @ApiOperation(value = "用户点击广告状态", notes = "用户点击广告状态")
    @GetMapping(value = "/getStatus")
    public Result<Boolean> getStatus(HttpServletRequest request) {
        // 获取点击次数和最后一次点击时间
        Integer currentUserClickCount = appMyProjectClickdetailService.getCurrentUserClickCount();
        if (currentUserClickCount > 40)//每天点击20次之后，每个半小时点击一次
        {
            AppMyProjectClickdetail lastClick = appMyProjectClickdetailService.getLastClick();
            Instant instant = lastClick.getCreateTime().toInstant();
            LocalDateTime lastDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime().plusMinutes(5);
            LocalDateTime now = LocalDateTime.now();
            if (now.isAfter(lastDateTime)) {
                System.out.println("当前时间大于上次时间加上半小时");
            } else {
                return Result.OK(false);
            }
        }
        // 每天点击40次之后，每个1小时后可点击
        return Result.OK(true);
    }

    @ApiOperation(value = "用户点击广告状态", notes = "用户点击广告状态")
    @GetMapping(value = "/getStatus2")
    public Result<ClickStatusVo> getStatus2(@RequestParam(name = "deviceId", required = true) String deviceId
            , HttpServletRequest request) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        ClickStatusVo vo = new ClickStatusVo();
        RequestVo requestVo = HttpServletRequestUtil.getDeviceInfoVo(request);
        AppUserDeviceLog deviceInfoVo = new AppUserDeviceLog();
        BeanUtils.copyProperties(requestVo, deviceInfoVo);
        List<AppDeviceFreeze> deviceFreezeList = deviceFreezeService.getList();

        if (deviceFreezeList != null && deviceFreezeList.size() > 0) {
            long count = deviceFreezeList.stream()
                    .filter(x -> x.getDeviceId().equals(deviceInfoVo.getDeviceId()) && x.getStatus().equals("0")).count();
            if (count > 0) {
                vo.setStatus(false);
                return Result.OK(vo);
            }
        }

        //保存设备请求日志
        deviceInfoVo.setUserId(sysUser.getId());
        deviceInfoVo.setRequestUrl("用户点击广告状态");
        deviceLogService.save(deviceInfoVo);
        //判断 设备id是否在禁止登录中
        SysUser byId = userService.getById(sysUser.getId());

        if (StringUtils.isNoneEmpty(byId.getClientId())) {
            byId.setClientId(deviceInfoVo.getDeviceId());
            userService.updateById(byId);
        }
        if (deviceInfoVo.getDeviceId().equals(byId.getClientId())) {
            vo.setStatus(true);
            // 获取所有奖励广告和广告位状态为0的广告
            List<AppSpace> spaceList = spaceService.getList().stream().
                    filter(x -> x.getSpaceType().equals(0) && x.getSpaceState().equals(0)).collect(Collectors.toList());
            // 附上广告位ID
            if (spaceList != null && spaceList.size() > 0) {
                Collections.shuffle(spaceList); // 这会改变list的顺序，但不会影响后续的操作。
                vo.setSpaceId(spaceList.get(0).getSpaceId());
            } else {
                vo.setSpaceId("103437211");
            }
            // 点击次数，大于20条后开始管控
            Integer clickCount = appMyProjectClickdetailService.getClickCountByDeviceId(deviceId, sysUser.getId());
            Integer interval = 0;
            if (clickCount > 3) {
                // 大于3条小于10条广告，间隔1分钟
                if (clickCount > 0 && clickCount <= 10) {
                    interval = 30;
                } else if (clickCount > 10 && clickCount <= 30) {
                    //大于10条小于20条，间隔5分钟
                    interval = 60;
                } else if (clickCount > 30) {
                    //大于40条，间隔30分钟
                    interval = 60 * 60;
                }
            }
            // 如果持续3条以上，小于1000金币，限制10分钟一条广告。

            // 最后一条记录点击记录
            AppMyProjectClickdetail lastClick = appMyProjectClickdetailService.getLastClickDetail(deviceId, sysUser.getId());
            if (ObjectUtils.isNull(lastClick)) {
                vo.setStatus(true);
            } else {
                Instant instant = lastClick.getCreateTime().toInstant();
                LocalDateTime lastDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime().plusSeconds(interval);
                LocalDateTime now = LocalDateTime.now();
                if (now.isAfter(lastDateTime)) {
                    vo.setStatus(true);
                } else {
                    vo.setStatus(false);
                    ZonedDateTime zonedDateTime = lastDateTime.atZone(ZoneId.systemDefault());
                    Date date = Date.from(zonedDateTime.toInstant());
                    vo.setNextClick(date);
                }
            }
            // 生成一条 金币奖励记录，如果广告平台有返回数据修改获得奖励金额。
            vo.setCode(UUID.randomUUID().toString(true));
            // 每天点击40次之后，每个1小时后可点击
            return Result.OK(vo);
        } else {
            vo.setStatus(false);
            AppMyProjectClickdetail lastClick = appMyProjectClickdetailService.getLastClickDetail(deviceId, sysUser.getId());
            Instant instant = lastClick.getCreateTime().toInstant();
            LocalDateTime lastDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime().plusMinutes(5);
            ZonedDateTime zonedDateTime = lastDateTime.atZone(ZoneId.systemDefault());
            Date date = Date.from(zonedDateTime.toInstant());
            vo.setNextClick(date);
            return Result.OK(vo);
        }
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "app_my_project_clickdetail-通过id查询", notes = "app_my_project_clickdetail-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<AppMyProjectClickdetail> queryById(@RequestParam(name = "id", required = true) String id) {
        AppMyProjectClickdetail appMyProjectClickdetail = appMyProjectClickdetailService.getById(id);
        if (appMyProjectClickdetail == null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(appMyProjectClickdetail);
    }

    @ApiOperation(value = "每日统计", notes = "每日统计")
    @GetMapping(value = "/dailyStatistics")
    public Result<List<ClickDetailDayStatisticsVo>> dailyStatistics() {
        LambdaQueryWrapper<AppMyProjectClickdetail> queryWrapper = Wrappers.lambdaQuery();
        LocalDateTime startOfDay = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
        LocalDateTime endOfDay = LocalDateTime.now().withHour(23).withMinute(59).withSecond(59).withNano(999999999);
        queryWrapper.between(AppMyProjectClickdetail::getCreateTime, startOfDay, endOfDay);
        List<AppMyProjectClickdetail> dataList = appMyProjectClickdetailService.list(queryWrapper);
        Map<String, List<AppMyProjectClickdetail>> groupBySdkList = dataList.stream()
                .collect(Collectors.groupingBy(AppMyProjectClickdetail::getSdkName));
        List<ClickDetailDayStatisticsVo> list = new ArrayList<>();
        double allEcpm = 0.0;
        for (Map.Entry<String, List<AppMyProjectClickdetail>> entry : groupBySdkList.entrySet()) {
            String sdkName = entry.getKey();
            double ecpm = 0.0;
            for (AppMyProjectClickdetail _detail : entry.getValue()) {
                ecpm += Double.parseDouble(_detail.getEcpm());
            }
            ClickDetailDayStatisticsVo v = new ClickDetailDayStatisticsVo();
            v.setSdkName(sdkName);
            v.setSumNum(ecpm);
            v.setCountNum(entry.getValue().size());
            allEcpm += ecpm;
            list.add(v);
        }
        ClickDetailDayStatisticsVo v = new ClickDetailDayStatisticsVo();
        v.setSdkName("ALL");
        v.setSumNum(allEcpm);
        v.setCountNum(dataList.size());
        list.add(v);
        return Result.OK(list);
    }
}
